home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_c / ems4c.zip / EMM_TEST.C < prev    next >
Text File  |  1993-07-26  |  10KB  |  386 lines

  1. /*
  2. **                ---  emm_test.c ---
  3. **
  4. **  EXAMPLE CODE: The program tests each of the EMM4C library functions, and
  5. **  exercises the page to frame mapping function by generating random mapping
  6. **  requests. To run, type:
  7. **
  8. **            EMM_TEST <Pages> <Iterations> <MinSize> <MaxSize>
  9. **
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <dos.h>
  15. #include "emm4c.h"
  16.  
  17. #define MANAGED_PAGES  50
  18. #define NUMBER_HANDLES 25
  19. #define NUMBER_SLOTS   25
  20. #ifndef FALSE
  21. #define FALSE 0
  22. #define TRUE !FALSE
  23. #endif
  24.  
  25. #define BYTE unsigned char
  26. #define WORD unsigned int
  27.  
  28. int ManagedPages;
  29. int ManagedHandles = NUMBER_HANDLES;
  30. int NumberSlots = NUMBER_SLOTS;
  31. int NumberLaps;
  32. unsigned int MinSize;
  33. unsigned int MaxSize;
  34.  
  35. struct StateTag
  36. {int  Handle;     /* returned handle */
  37.  WORD Size;       /* size in bytes */
  38.  char Mark;       /* mark character ('A' to 'Z') */
  39. } State[NUMBER_SLOTS];
  40.  
  41. WORD NbrAlloc = 0;        /* number emmAlloc() calls */
  42. WORD NbrFree = 0;         /* number emmFree() calls */
  43. WORD MinAlloc = 0x7fff;   /* smallest allocation */
  44. WORD MaxAlloc = 0;        /* largest allocation */
  45. WORD AvgAlloc = 0;        /* average allocation size */
  46. int Seed = 54321;
  47.  
  48. #define MAKE_FAR_PTR(seg,off) ((void far *)(((unsigned long)(seg)<<16)|(unsigned)(off)))
  49.  
  50. void main(argc,argv)
  51. int argc;
  52. char *argv[];
  53. {int i, k;        /* loop counters */
  54.  char c;
  55.  int Lap;         /* main loop counter */
  56.  int Slot;        /* state slot [index] */
  57.  int Code;        /* EMM function return code */
  58.  char far *FarCharPtr;  /* generic far character pointer */
  59.  int far *FarIntPtr;    /* generic far integer pointer */
  60.  WORD FreePages = 0;
  61.  WORD FreeParas = 0;
  62.  /* begin */
  63.  puts("***");
  64.  puts("*** EMM_TEST: Version 1.0");
  65.  puts("***");
  66.  if(argc!=5)
  67.    {puts("Usage: EMM_TEST <Pages> <Iterations> <MinSize> <MaxSize>");
  68.     puts("where:");
  69.     puts("        <Pages> = # pages to manage");
  70.     puts("   <Iterations> = # emmAlloc() / emmFree() calls");
  71.     puts("      <MinSize> = Minimum allocation size (bytes)");
  72.     puts("      <MaxSize> = Maximum allocation size (bytes)");
  73.     exit(1);
  74.    }
  75.  /* fetch & verify parameters */
  76.  if(!Range(argv[1],&ManagedPages,1,MANAGED_PAGES,"Page")) exit(2);
  77.  if(!Range(argv[2],&NumberLaps,1,1000,"Iteration")) exit(2);
  78.  if(!Range(argv[3],&MinSize, 1,65534,"MinSize")) exit(2);
  79.  if(!Range(argv[4],&MaxSize, (1+MinSize),65535,"MaxSize")) exit(2);
  80.  /* echo parameters */
  81.  printf("***       Pages = %d (%d KB)\n",ManagedPages,(16*ManagedPages));
  82.  printf("***  Iterations = %d\n",NumberLaps);
  83.  printf("***    Min Size = %u bytes\n",MinSize);
  84.  printf("***    Max Size = %u bytes\n",MaxSize);
  85.  puts("***");
  86.  puts("Initializing...");
  87.  for(i=0;i<NumberSlots;i++)
  88.    {State[i].Handle = -1;
  89.     State[i].Size = 0;
  90.     State[i].Mark = '@';
  91.    }
  92.  srand(Seed);
  93.  CheckError( emmInit(ManagedPages,ManagedHandles) );
  94.  printf("Ready to start test. Type any key...");
  95.  while( !kbhit() );
  96.  putchar( getchar() );
  97.  /* start test */
  98.  for(Lap=1;Lap<=NumberLaps;Lap++)
  99.    {/* user cancels ? */
  100.     if(kbhit())
  101.        {printf("\nUSER cancels...");
  102.         break;
  103.        }
  104.     /* allocate if no buffers currently allocated */
  105.     if(NbrAlloc==NbrFree)
  106.       {/* allocate another EMS buffer */
  107.        Slot = Allocate();
  108.        if(Slot>=0)
  109.          {printf("(%d) Allocating %u bytes (%d paragraphs)\n",
  110.            Lap,State[Slot].Size,(State[Slot].Size+15)/16);
  111.          }
  112.       }
  113.     else if((NbrAlloc-NbrFree)==NumberSlots)
  114.       {/* free an EMS buffer */
  115.        Slot = Frees();
  116.        if(Slot>=0)
  117.          {printf("(%d) Freeing %u bytes\n",Lap,State[Slot].Size);
  118.           State[Slot].Size = 0;
  119.          }
  120.       }
  121.     else
  122.       {/* decide to allocate or free */
  123.        i = Random(100);
  124.        if(i<=52)
  125.          {/* allocate 52% of the time */
  126.           Slot = Allocate();
  127.           if(Slot>=0)
  128.             {printf("(%d) Allocating %u bytes (%d paragraphs)\n",
  129.                Lap,State[Slot].Size,State[Slot].Size/16);
  130.             }
  131.          }
  132.        else
  133.          {/* free 48% of the time */
  134.           Slot = Frees();
  135.           if(Slot>=0)
  136.             {printf("(%d) Freeing %u bytes\n",Lap,State[Slot].Size);
  137.              State[Slot].Size = 0;
  138.             }
  139.          }
  140.       }
  141.    } /* end for(Lap) */
  142.  /* all done */
  143.  DumpSlots();
  144.  printf("NbrAlloc=%u NbrFree=%u\n",NbrAlloc,NbrFree);
  145.  printf("MinAlloc=%u MaxAlloc=%u AvgAlloc=%u\n",MinAlloc,MaxAlloc,AvgAlloc);
  146.  emmPages(&FreePages,&FreeParas);
  147.  printf("FreePages=%d FreeParas=%u\n",FreePages,FreeParas);
  148.  PageDump(FALSE);
  149.  CheckError( emmDone() );
  150. } /* end main */
  151.  
  152.  
  153. int FindFreeSlot()
  154. {int i;
  155.  for(i=0;i<NumberSlots;i++) if(State[i].Handle<0) return(i);
  156.  return(-1);
  157. } /* end FindFreeSlot */
  158.  
  159.  
  160. int ChooseSlot()
  161. {int i;
  162.  int List[NUMBER_SLOTS];
  163.  int Count = 0;
  164.  /* put all active slots in list */
  165.  for(i=0;i<NumberSlots;i++) if(State[i].Handle>=0)
  166.     {List[Count++] = i;
  167.     }
  168.  /* choose slot at random */
  169.  if(Count==0) return(-1);
  170.  i = Random(Count);
  171.  return( List[i] );
  172. } /* end ChooseSlot */
  173.  
  174.  
  175. int Allocate()
  176. {int i, k;
  177.  int Slot;
  178.  int Code;
  179.  WORD Size;             /* size of buffer to allocate */
  180.  char Mark;             /* mark character */
  181.  int Handle;            /* handle returned from emmAlloc() */
  182.  WORD Segment;          /* segment value return from emmLock() */
  183.  WORD Offset;           /* offset value returned from emmLock() */
  184.  char far *FarCharPtr;  /* generic far character pointer */
  185.  int Page;
  186.  int Dummy;
  187.  float Ratio;
  188.  /* find a free slot */
  189.  Slot = FindFreeSlot();
  190.  if(Slot<0)
  191.    {printf("*** Allocate: No slots available...\n");
  192.     return(-1);
  193.    }
  194.  /* choose a size */
  195.  Size = MinSize + Random(MaxSize - MinSize);
  196.  /* compute minimum & maximum allocations */
  197.  if(Size>MaxAlloc) MaxAlloc = Size;
  198.  if(Size<MinAlloc) MinAlloc = Size;
  199. #if 0
  200.  printf("*** Allocate: Request to allocate %u bytes\n",Size);
  201. #endif
  202.  /* allocate EMS page(s) */
  203.  Handle = emmAlloc(Size);
  204.  if(Handle<0)
  205.    {/* could not allocate! */
  206.     printf("ERROR allocating %u bytes\n",Size);
  207.     return(-1);
  208.    }
  209.  else
  210.    {/* allocation is successful */
  211.     NbrAlloc++;
  212.     /* update average allocation size */
  213.     Ratio = (float)(NbrAlloc-1) / (float)NbrAlloc;
  214.     AvgAlloc = (int) ( Ratio*(float)AvgAlloc + (float)Size/(float)NbrAlloc );
  215.     /* save stats in state variable struct */
  216.     State[Slot].Handle = Handle;
  217.     State[Slot].Size = Size;
  218.     /* select a Mark & record it */
  219.     Mark = 'A' + Random(26);
  220.     State[Slot].Mark = Mark;
  221.     /* get EMS buffer address */
  222.     Code = emmLock(Handle,&Segment);
  223.     if(Code==0)
  224.       {/* save Mark in EMS buffer */
  225.        FarCharPtr = MAKE_FAR_PTR(Segment,0);
  226.        for(k=0;k<Size;k++) *FarCharPtr++ = Mark;
  227.        emmUnlock(Handle);
  228.       }
  229.     else CheckError(Code);
  230.     return(Slot);
  231.    }
  232. } /* end Allocate */
  233.  
  234.  
  235. int VerifyMark(Slot)
  236. int Slot;
  237. {int i;
  238.  WORD k;
  239.  WORD Size;
  240.  char c;
  241.  int Handle;
  242.  char Mark;
  243.  int Code;
  244.  WORD Segment;
  245.  WORD Offset;
  246.  char far *FarCharPtr;
  247.  /* begin */
  248.  Handle = State[Slot].Handle;
  249.  if(Handle<0) return(0);
  250.  Mark = State[Slot].Mark;
  251.  Size = State[Slot].Size;
  252.  Code = emmLock(Handle,&Segment);
  253.  if(Code==0)
  254.    {/* check Mark in EMS buffer */
  255.     FarCharPtr = MAKE_FAR_PTR(Segment,0);
  256.     /* verify mark */
  257.     for(k=0;k<Size;k++)
  258.       {c = *FarCharPtr;
  259.        /*if(k<5) printf("%c",c);*/
  260.        if(c != Mark)
  261.          {printf("ERROR: Found mark = '%c' not '%c' (index=%d Segment=%x Size=%d) \n",
  262.             *FarCharPtr,Mark,k,Segment,Size);
  263.           emmUnlock(Handle);
  264.           DumpSlots();
  265.           emmDone();
  266.           exit(1);
  267.          }
  268.        /* next byte */
  269.        FarCharPtr++;
  270.       } /* end for(k) */
  271.     /* mark is verified */
  272.     emmUnlock(Handle);
  273.    } /* end if(Code) */
  274.  return(0);
  275. } /* end VerifyMark */
  276.  
  277.  
  278. int Frees()
  279. {int k;
  280.  int Slot;
  281.  int Code;
  282.  int Handle;
  283.  char Mark;
  284.  WORD Size;
  285.  char far *FarCharPtr;
  286.  /* choose slot to free at random */
  287.  Slot = ChooseSlot();
  288.  if(Slot>=0)
  289.    {
  290.     Handle = State[Slot].Handle;
  291.     VerifyMark(Slot);
  292.     Code = emmFree(Handle);
  293.     NbrFree++;
  294.     if(Code==0)
  295.       {State[Slot].Handle = -1;
  296.        State[Slot].Mark = '#';
  297.        return(Slot);
  298.       }
  299.     else CheckError(Code);
  300.    }
  301.  return(-1);
  302. } /* end Free */
  303.  
  304.  
  305. int DumpSlots()
  306. {int i;
  307.  int Handle;
  308.  int Code;
  309.  WORD k;
  310.  WORD Size;
  311.  WORD Segment;
  312.  WORD Offset;
  313.  WORD Limit;
  314.  char far *FarCharPtr;
  315.  int LastSlot = 0;
  316.  /* begin */
  317.  for(i=NumberSlots-1;i>0;i--) if(State[i].Handle != -1)
  318.     {LastSlot = i;
  319.      break;
  320.     }
  321.  printf("***** ManagedPages=%d (%d KB) ***** \n",ManagedPages,16*ManagedPages);
  322.  printf("Slot Handle  Size  Mark  Data...\n");
  323.  printf("==== ======  ====  ====  ====\n");
  324.  for(i=0;i<=LastSlot;i++)
  325.    {
  326.     printf("%4d %5d %6u    %c   ",
  327.       i,State[i].Handle,State[i].Size,State[i].Mark);
  328.     Handle = State[i].Handle;
  329.     if(Handle>=0)
  330.       {Code = emmLock(Handle,&Segment);
  331.        if(Code==0)
  332.          {/* get pointer to EMS block */
  333.           FarCharPtr = MAKE_FAR_PTR(Segment,0);
  334.           Size = State[i].Size;
  335.           Limit = Size;
  336.           if(Limit>17) Limit = 17;
  337.           for(k=0;k<Limit;k++)
  338.              {printf("%c",*FarCharPtr);
  339.               FarCharPtr++;
  340.              }
  341.           /* display last character in allocation */
  342.           FarCharPtr = MAKE_FAR_PTR(Segment,Size-1);
  343.           printf("...%c",*FarCharPtr++);
  344.           emmUnlock(Handle);
  345.          }
  346.       } /* end if */
  347.     printf("\n");
  348.    }
  349.  return(0);
  350. } /* end DumpSlot */
  351.  
  352. int CheckError(Code)
  353. int Code;
  354. {if(Code<0)
  355.   {emmError(Code);
  356.   }
  357.  return(Code);
  358. }
  359.  
  360. int Random(Modulo)
  361. WORD Modulo;
  362. {WORD r;
  363.  /* rand() returns [0..32767] */
  364.  r = (WORD) rand();
  365.  if(Modulo<=32767) return(r%Modulo);
  366.  return( (r+r) % Modulo);
  367. } /* end Random */
  368.  
  369. int Range(String,ValuePtr,MinValue,MaxValue)
  370. char *String;
  371. unsigned int *ValuePtr;
  372. unsigned int MinValue;
  373. unsigned int MaxValue;
  374. {unsigned int Value;
  375.  Value = (unsigned int) atoi(String);
  376.  if(Value<MinValue)
  377.    {printf("ERROR: parameter (%s) < minimum (%d)\n",String,MinValue);
  378.     return(FALSE);
  379.    }
  380.  if(Value>MaxValue)
  381.    {printf("ERROR: parameter (%s) > maximum (%d)\n",String,MaxValue);
  382.     return(FALSE);
  383.    }
  384.  *ValuePtr = Value;
  385.  return(TRUE);
  386. } /* range */